// Application implementation for MacOS X Carbon
// Copyright 2006 (C) Ralph Thomas

#include <toolkit/application.h>
#include "carbon_safe.hpp"
#include <vector>
#include <algorithm>

namespace toolkit {
	class applicationImpl : public application {
		typedef std::vector<idle*> idleList;
		idleList	_idlers;
		//
		/// Call all of the idle handlers.
		//
		void callIdlers() {
			//
			// Make a safe copy of the idle handler list that won't get
			// modified if any of the handlers wish to remove themselves
			// while we are iterating through this list.
			//
			idleList safe( _idlers );
			const idleList::iterator first( safe.begin() );
			const idleList::iterator last( safe.end() );
			for( idleList::iterator i = first; i != last; i++ ) {
				//
				// If we can still find *i inside _idlers then it's okay to
				// call it.
				//
				if( std::find( _idlers.begin(), _idlers.end(), *i ) != _idlers.end() )
					(*i)->process();
			}
		}
	  public:
		applicationImpl() {}
		virtual ~applicationImpl() {}
		//
		// from toolkit/application.h
		//
		virtual initReturn init() {
			//
			// We register as an Appearance Manager client so that we can
			// use the Appearance Manager API to query widget metrics (and
			// to draw custom widgets). As we don't currently handle any
			// Apple Events, it's not clear what this call does.
			//
			RegisterAppearanceClient();
			return kOk;
		}
		virtual void run() {
			//
			// XXX: We need to support idle calls in here.
			//
			RunApplicationEventLoop();
		}
		virtual void quit() { QuitApplicationEventLoop(); }
		virtual void addIdle( idle* idleHandler, unsigned int ) {
			_idlers.push_back( idleHandler );
		}
		virtual void removeIdle( idle* idleHandler ) {
			idleList::iterator i( std::find( _idlers.begin(), _idlers.end(),
				idleHandler ) );
			if( i != _idlers.end() ) _idlers.erase( i );
		}
	};
	application& application::getInstance() {
		static applicationImpl app;
		return app;
	}
}
